<template>
    <div>
        <div class="form">
            <el-form :inline="true" :model="searchData" class="demo-form-inline">
                <el-form-item>
                    <el-select v-model="searchData.status" class="m-2" placeholder="请选择广告状态" size="large" clearable>
                        <el-option v-for="item in adStatusMap" :key="item.value" :label="item.name"
                            :value="item.value" />
                    </el-select>
                </el-form-item>
                <el-form-item>
                    <el-select v-model="searchData.type" class="m-2" placeholder="请选择广告类型" size="large" clearable>
                        <el-option v-for="item in adTypeMap" :key="item.value" :label="item.name" :value="item.value" />
                    </el-select>
                </el-form-item>
                <el-form-item>
                    <el-button type="primary" :icon="Search" @click="handelSearch">查找</el-button>
                </el-form-item>
                <el-form-item>
                    <el-button type="primary" :icon="Plus" @click="handelAdd">添加</el-button>
                </el-form-item>
            </el-form>
        </div>
        <div>
            <el-table :data="tableData" id="table" style="width: 100%" border
                :header-cell-style="{ 'text-align': 'center' }" :cell-style="{ 'text-align': 'center' }">
                <el-table-column label="广告ID" prop="id" />
                <el-table-column label="广告标题" prop="title" />
                <el-table-column label="广告图片">
                    <template #default="scope">
                        <template v-if="adTypeMap.find(item => item.value == scope.row.type)?.picRequire">
                            <el-popover trigger="hover" placement="right" width="auto"
                                :popper-style="{ 'background-color': scope.row.color }">
                                <template #default>
                                    <img :src="scope.row.imgUrl" alt="" width="200">
                                </template>
                                <template #reference>
                                    <img :src="scope.row.imgUrl" alt="" width="50">
                                </template>
                            </el-popover>
                        </template>
                        <el-tag type="info" v-else>此类型无需图片</el-tag>
                    </template>
                </el-table-column>
                <el-table-column label="广告类型">
                    <template #default="scope">
                        <div v-for="item in adTypeMap" :key="item.value">
                            <el-tag v-if="scope.row.type == item.value">{{ item.name }}</el-tag>
                        </div>
                    </template>
                </el-table-column>
                <el-table-column label="广告状态">
                    <template #default="scope">
                        <el-tag :type="scope.row.status == 1 ? 'success' : 'danger'">
                            {{ scope.row.status == 1 ? '激活' : '冻结' }}
                        </el-tag>
                    </template>
                </el-table-column>
                <el-table-column label="关联类型" prop="unionType">
                    <template #default="scope">
                        <div v-for="item in adUinonTypeMap" :key="item.value">
                            <el-tag type="warning" v-if="scope.row.unionType == item.value">{{ item.name }}</el-tag>
                        </div>
                    </template>
                </el-table-column>
                <el-table-column label="关联值[ID]" prop="unionValue" />
                <el-table-column label="创建时间">
                    <template #default="scope">
                        {{ new Date(scope.row.gmtCreate).friendTime(0) }}
                    </template>
                </el-table-column>
                <el-table-column label="操作" width="180">
                    <template #default="scope">
                        <el-button size="small" type="primary" @click="handelEdit(scope.row)">编辑</el-button>
                        <el-button size="small" type="danger" @click="handelDelete(scope.row)">删除</el-button>
                    </template>
                </el-table-column>
            </el-table>
        </div>
        <div>
            <Pagetion v-bind="pagetio" @page-change="pageChange"></Pagetion>
        </div>
        <div>
            <el-backtop target=".el-main" :right="100" :bottom="100" ref="backTop" :visibility-height="20" />
        </div>

        <div>
            <el-dialog v-model="dialogFormVisible" :title="title" destroy-on-close @opened="openDialog">
                <el-form ref="ruleFormRef" :model="ruleForm" status-icon :rules="rules" label-width="120px"
                    class="demo-ruleForm">
                    <el-form-item label="广告标题" prop="title">
                        <el-input v-model="ruleForm.title" autocomplete="off" clearable />
                    </el-form-item>
                    <el-form-item label="广告类型" prop="type">
                        <el-select v-model="ruleForm.type" class="m-2" placeholder="请选择广告类型" @change="handelClear"
                            clearable>
                            <el-option v-for="item in adTypeMap" :key="item.value" :label="item.name"
                                :value="item.value" />
                        </el-select>
                    </el-form-item>
                    <el-form-item label="广告图片" prop="imgUrl" id="upload" ref="uploadRef"
                        v-if="adTypeMap.find(item => item.value == ruleForm.type)?.picRequire">
                        <el-upload class="avatar-uploader" :headers="headers" :show-file-list="false"
                            :before-upload="beforeAvatarUpload" :on-success="handleAvatarSuccess"
                            action="/upload/admin">
                            <img v-if="ruleForm.imgUrl" :src="ruleForm.imgUrl" class="avatar" />
                            <el-icon v-else class="avatar-uploader-icon">
                                <Plus />
                            </el-icon>
                        </el-upload>
                    </el-form-item>
                    <el-form-item label="广告状态" required>
                        <el-switch v-model="ruleForm.status" :active-value="1" :inactive-value="0"
                            style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ccc" />
                    </el-form-item>
                    <el-form-item label="关联类型" prop="unionType">
                        <el-select v-model="ruleForm.unionType" class="m-2" placeholder="请选择关联类型"
                            @change="ruleForm.unionValue = undefined" clearable>
                            <el-option v-for="item in adUinonTypeMap" :key="item.value" :label="item.name"
                                :value="item.value"
                                :disabled="ruleForm.type == undefined || adTypeMap.find(item => item.value == ruleForm.type)?.unionTypes.findIndex(items => items == item.value) == -1" />
                        </el-select>
                    </el-form-item>
                    <el-form-item label="商品" v-if="ruleForm.unionType == 1" prop="unionValue">
                        <el-cascader :options="productData" v-model="ruleForm.unionValue" placeholder="请选择商品" clearable
                            :props="{ checkStrictly: false, children: 'children', value: 'id', label: 'label', emitPath: false }" />
                    </el-form-item>
                    <el-form-item label="类目" v-if="ruleForm.unionType == 2" prop="unionValue">
                        <el-cascader :options="categoryData" v-model="ruleForm.unionValue" placeholder="请选择类目" clearable
                            :props="{ checkStrictly: true, children: 'childrenList', value: 'id', label: 'title', emitPath: false }" />
                    </el-form-item>
                    <el-form-item label="关键字" v-if="ruleForm.unionType == 3" prop="unionValue">
                        <el-input v-model="ruleForm.unionValue" autocomplete="off" clearable />
                    </el-form-item>
                    <el-form-item label="功能页面" v-if="ruleForm.unionType == 4" prop="unionValue">
                        <el-select v-model="ruleForm.unionValue" placeholder="请选择功能页面" clearable>
                            <el-option v-for="item in functionPages" :key="item.value" :label="item.name"
                                :value="item.value" />
                        </el-select>
                    </el-form-item>
                </el-form>
                <template #footer>
                    <span class="dialog-footer">
                        <el-button @click="dialogFormVisible = false">取消</el-button>
                        <el-button type="primary" @click="submitForm(ruleFormRef)">确定</el-button>
                    </span>
                </template>
            </el-dialog>
        </div>
    </div>
</template>

<script lang="ts" setup>
import { ref, reactive, nextTick, watch } from 'vue'
import { post } from '@/http/request';
import { Search, Plus, } from '@element-plus/icons-vue'
import { ClassPagination, ClassAdvertEdit } from "#/index";
import Pagetion from "@/components/pagetion/Pagetion.vue";//分页
import "@/utils/DateFormatter";//友好日期
import { theColorFn } from "@/utils/theColor"
import { ElMessage, ElMessageBox } from 'element-plus';
import type { FormInstance } from 'element-plus'
import cookie from 'js-cookie';
import type { UploadProps } from 'element-plus'

const backTop = ref()//回到顶部组件节点
const pagetio = reactive(new ClassPagination())//实例化分页数据
const tableData = ref<TypeAdvert[]>([])//接收表格数据
const uploadRef = ref()//上传图片功能节点
const ruleFormRef = ref<FormInstance>()
const dialogFormVisible = ref(false)//弹窗是否显示
const title = ref("")//弹窗标题
const categoryData = ref([])//类目数据
const productData = ref([])//商品数据
const defaultImage = 'https://www.baidu.com/img/flexible/logo/pc/result.png'//默认图片

// 上传图片需配置的请求头
const headers = reactive({
    AdminToken: cookie.get('token')
})

const ruleForm: TypeAdver = reactive({
    id: 0,//广告id
    title: '',//广告标题
    type: undefined,//广告类型
    imgUrl: '',//广告图片
    status: 1,//广告状态
    unionType: undefined,//关联类型
    unionValue: undefined,//关联类型相关的类型种类
    color: ''//广告图片背颜色
})
const form = reactive({ ...ruleForm })

// 验证规则
const rules = reactive({
    // 广告名称
    title: [{ required: true, message: '请输入广告名称', trigger: 'blur' },],
    // 广告类型
    type: [{ required: true, message: '请选择广告类型', trigger: 'change' },],
    // 关联类型
    unionType: [{ required: true, message: '请选择关联类型', trigger: 'change' },],
    // 关联值
    unionValue: [{ required: true, message: '关联值不能为空', trigger: ['change', 'blur'] },],
})

//广告关联类型
const adUinonTypeMap = [
    { value: 1, name: '商品' },
    { value: 2, name: '类目' },
    { value: 3, name: '关键字' },
    { value: 4, name: '功能页面' },
]

//广告类型
const adTypeMap = [
    { value: 1, unionTypes: [1, 2, 3, 4], picRequire: true, name: '轮播' },
    { value: 2, unionTypes: [2], picRequire: true, name: '分类精选' },
    { value: 3, unionTypes: [1, 2, 3, 4], picRequire: true, name: '横幅' },
    { value: 4, unionTypes: [1, 2, 3, 4], picRequire: true, name: '首页轮播下5按钮' },
    { value: 6, unionTypes: [1, 2, 3, 4], picRequire: false, name: '公告' },
    { value: 9, unionTypes: [1], picRequire: false, name: '商品推荐' },
]
//广告状态
const adStatusMap = [
    { value: 0, name: '冻结' },
    { value: 1, name: '激活' },
]

// 功能页面
const functionPages = [
    { value: '/pages/product/groupshop', name: '团购列表' },
    { value: '/pages/coupon/list', name: '优惠券列表' },
]

// 初始化数据传递的参数
let params = reactive({
    _gp: "admin.advert",
    _mt: "list",
    type: undefined,
    pageNo: pagetio.pageNo,
    limit: pagetio.pageSize,
    status: undefined
})

// 搜索需要的数据
let searchData = reactive({
    type: undefined,
    status: undefined
})

// 初始化数据
function loadInit() {
    post(params).then(res => {
        console.log(res);
        let { data, errmsg, errno } = res
        if (200 == errno) {
            tableData.value = data.items
            pagetio.total = data.total
        } else {
            ElMessage.error(errmsg)
        }
    })
}
loadInit()

// 搜索
function handelSearch() {
    params.type = searchData.type
    params.status = searchData.status
    loadInit()
}

// 添加打开弹窗
function handelAdd() {
    title.value = "创建"
    Object.assign(ruleForm, form)
    dialogFormVisible.value = true
}

// 编辑打开弹窗
function handelEdit(row: TypeAdvert) {
    console.log(row);

    if (1 == row.unionType || 2 == row.unionType) {
        row.unionValue = +row.unionValue
    }
    Object.assign(ruleForm, { ...row, adId: row.id })
    title.value = "编辑"
    dialogFormVisible.value = true
}

// 打开弹窗后
function openDialog() {
    if ('编辑' == title.value && uploadRef.value != null) {
        uploadRef.value.$el.style.backgroundColor = ruleForm.color
    }
}

// 图片上传成功的钩子函数
const handleAvatarSuccess: UploadProps['onSuccess'] = (
    response,
) => {
    if (200 == response.errno) {
        ruleForm.imgUrl = response.url // 得到上传图片成功的路径
        theColorFn(ruleForm.imgUrl, (callback: string) => {
            ruleForm.color = callback
        }) // 计算得到图片平均色
        loadInit()
    }
}

// 图片上传成功前的钩子函数
const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => {
    if (rawFile.size / 1024 / 1024 > 1) {
        ElMessage.error('图片大小不能超过1MB!')
        return false
    }
    return true
}

// 广告类型发生改变时清空图片、颜色、关联类型
function handelClear() {
    ruleForm.imgUrl = ""
    ruleForm.unionType = undefined
    ruleForm.color = ""
}

// 监听图片背景色
watch(([() => ruleForm.imgUrl]), ([newimgUrl]) => {
    if (newimgUrl == '' && uploadRef.value != null) {
        uploadRef.value.$el.style.backgroundColor = 'transparent'
    }
})

// 添加编辑请求
function submitForm(formEl: FormInstance | undefined) {
    if (!formEl) return
    formEl.validate((valid) => {
        if (valid) {
            if (6 == ruleForm.type || 9 == ruleForm.type) {
                ruleForm.imgUrl = defaultImage
            }
            if (ruleForm.imgUrl == "") return ElMessage.warning("请上传图片")
            let parameter = reactive({
                _gp: "admin.advert",
                _mt: title.value == '编辑' ? "edit" : "create",
                ...ruleForm
            })
            post(parameter).then(res => {
                let { errmsg, errno } = res
                if (200 == errno) {
                    dialogFormVisible.value = false
                    ElMessage.success(title.value == '编辑' ? '编辑成功' : '添加成功')
                    loadInit()
                } else {
                    ElMessage.error(errmsg)
                }
            })
        } else {
            return false
        }
    })
}

// 删除
function handelDelete(row: TypeAdvert) {
    let delParams = reactive({
        _gp: "admin.advert",
        _mt: "delete",
        type: row.type,
        adId: row.id,
    })
    ElMessageBox.confirm(
        '是否删除此广告？',
        '提示',
        {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning',
        }
    ).then(() => {
        post(delParams).then(res => {
            let { errno, errmsg } = res
            if (200 == errno) {
                ElMessage.success("删除成功")
                loadInit()
            } else {
                ElMessage.error(errmsg)
            }
        })
    })
}

// 请求弹窗类目数据
function popCategory() {
    let data = {
        _gp: 'admin.category',
        _mt: 'categoryTree'
    }
    post(data).then(res => {
        console.log(res);
        let { data, errno, errmsg } = res
        if (200 == errno) {
            categoryData.value = data
        } else {
            ElMessage.error(errmsg)
        }
    })
}
popCategory()

// 请求弹窗商品数据
function popProduct() {
    let data = {
        _gp: 'admin.product',
        _mt: 'getSpuBigTree'
    }
    post(data).then(res => {
        console.log(res);
        let { data, errno, errmsg } = res
        if (200 == errno) {
            productData.value = data
        } else {
            ElMessage.error(errmsg)
        }
    })
}
popProduct()

// 分页组件子传父自定义事件
const pageChange = (e: TypePage) => {
    params.pageNo = e._pageNo
    params.limit = e._pageSize
    loadInit()
    nextTick(() => {
        backTop.value.$el.click?.()
    })
}
</script>

<style lang="less" scoped>
.el-form-item {
    margin-right: 10px !important;
}

.el-select {
    width: 200px;
}

.el-dialog__body {
    .el-form-item {
        margin-bottom: 20px !important;
    }

    .el-input {
        width: 500px !important;
    }
}

.avatar-uploader .avatar {
    width: 178px;
    height: 178px;
    display: block;
}
</style>

<style>
.avatar-uploader .el-upload {
    border: 1px dashed var(--el-border-color);
    border-radius: 6px;
    cursor: pointer;
    position: relative;
    overflow: hidden;
    transition: var(--el-transition-duration-fast);
}

.avatar-uploader .el-upload:hover {
    border-color: var(--el-color-primary);
}

.el-icon.avatar-uploader-icon {
    font-size: 28px;
    color: #8c939d;
    width: 178px;
    height: 178px;
    text-align: center;
}
</style>